package simulaco.dao;

import gminet.infra.dao.DataAccessObject;
import gminet.infra.db.TransactionException;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import simulaco.dto.Questao;
import simulaco.dto.SimuladoUsuario;
import simulaco.dto.SimuladoUsuarioQuestao;
import simulaco.dto.SimuladoUsuarioSituacao;
import simulaco.dto.Situacao;

public class SimuladoUsuarioQuestaoDAO extends DataAccessObject {

    public static SimuladoUsuarioQuestao findByPK(SimuladoUsuarioQuestao simuladoQuestao, Connection conn)
            throws TransactionException {

        SimuladoUsuario simulado = simuladoQuestao.getSimuladoUsuario();
        Questao questao = simuladoQuestao.getQuestao();
        return findByPK(simulado.getUsuario().getCodigo(), simulado.getCodigo(), questao.getConcurso().getCodigo(),
                questao.getMateria().getCodigo(), questao.getCodigo(), conn);
    }

    public static SimuladoUsuarioQuestao findByPK(int codigoUsuario, int codigoSimulado, int codigoConcurso,
            int codigoMateria, int codigoQuestao, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("SELECT A.CD_USUARIO             CD_USUARIO            ");
        sbSql.append("     , A.CD_SIMULADO            CD_SIMULADO           ");
        sbSql.append("     , S.TX_INDENTIFICACAO      TX_INDENTIFICACAO     ");
        sbSql.append("     , S.TX_DESCRICAO           TX_DESCRICAO          ");
        sbSql.append("     , S.ID_SITUACAO            ID_SITUACAO_SIMULADO  ");
        sbSql.append("     , S.TS_CADASTRO            TS_CADASTRO_SIMULADO  ");
        sbSql.append("     , A.CD_CONCURSO            CD_CONCURSO           ");
        sbSql.append("     , A.CD_MATERIA             CD_MATERIA            ");
        sbSql.append("     , A.CD_QUESTAO             CD_QUESTAO            ");
        sbSql.append("     , Q.ID_SITUACAO            ID_SITUACAO_QUESTAO   ");
        sbSql.append("     , Q.TX_QUESTAO             TX_QUESTAO            ");
        sbSql.append("     , Q.TX_COMENTARIO          TX_COMENTARIO_QUESTAO ");
        sbSql.append("     , A.CD_ITEM_RESPOSTA       CD_ITEM_RESPOSTA      ");
        sbSql.append("     , A.TX_COMENTARIO          TX_COMENTARIO_RESPOSTA");
        sbSql.append("  FROM SIMULADO_USUARIO_QUESTAO A ");
        sbSql.append("     , SIMULADO_USUARIO         S ");
        sbSql.append("     , QUESTAO                  Q ");
        sbSql.append(" WHERE A.CD_USUARIO  = S.CD_USUARIO  ");
        sbSql.append("   AND A.CD_SIMULADO = S.CD_SIMULADO ");
        sbSql.append("   AND A.CD_CONCURSO = Q.CD_CONCURSO ");
        sbSql.append("   AND A.CD_MATERIA  = Q.CD_MATERIA  ");
        sbSql.append("   AND A.CD_QUESTAO  = Q.CD_QUESTAO  ");
        sbSql.append("   AND A.CD_USUARIO  = ? ");
        sbSql.append("   AND A.CD_SIMULADO = ? ");
        sbSql.append("   AND A.CD_CONCURSO = ? ");
        sbSql.append("   AND A.CD_MATERIA  = ? ");
        sbSql.append("   AND A.CD_QUESTAO  = ? ");

        SimuladoUsuarioQuestao simuladoQuestao = null;
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, codigoUsuario);
            setInt(ps, pos++, codigoSimulado);
            setInt(ps, pos++, codigoConcurso);
            setInt(ps, pos++, codigoMateria);
            setInt(ps, pos++, codigoQuestao);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                simuladoQuestao = fromResultSet(rs);
            }
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoUsuarioQuestaoDAO.findByPK (" + sqle.getMessage() + ")");
        }
        return simuladoQuestao;
    }

    public static List<SimuladoUsuarioQuestao> findBySimulado(int codigoUsuario, int codigoSimulado, Connection conn)
            throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("SELECT A.CD_USUARIO             CD_USUARIO            ");
        sbSql.append("     , A.CD_SIMULADO            CD_SIMULADO           ");
        sbSql.append("     , S.TX_INDENTIFICACAO      TX_INDENTIFICACAO     ");
        sbSql.append("     , S.TX_DESCRICAO           TX_DESCRICAO          ");
        sbSql.append("     , S.ID_SITUACAO            ID_SITUACAO_SIMULADO  ");
        sbSql.append("     , S.TS_CADASTRO            TS_CADASTRO_SIMULADO  ");
        sbSql.append("     , A.CD_CONCURSO            CD_CONCURSO           ");
        sbSql.append("     , A.CD_MATERIA             CD_MATERIA            ");
        sbSql.append("     , A.CD_QUESTAO             CD_QUESTAO            ");
        sbSql.append("     , Q.ID_SITUACAO            ID_SITUACAO_QUESTAO   ");
        sbSql.append("     , Q.TX_QUESTAO             TX_QUESTAO            ");
        sbSql.append("     , Q.TX_COMENTARIO          TX_COMENTARIO_QUESTAO ");
        sbSql.append("     , A.CD_ITEM_RESPOSTA       CD_ITEM_RESPOSTA      ");
        sbSql.append("     , A.TX_COMENTARIO          TX_COMENTARIO_RESPOSTA");
        sbSql.append("  FROM SIMULADO_USUARIO_QUESTAO A ");
        sbSql.append("     , SIMULADO_USUARIO         S ");
        sbSql.append("     , QUESTAO                  Q ");
        sbSql.append(" WHERE A.CD_USUARIO  = S.CD_USUARIO  ");
        sbSql.append("   AND A.CD_SIMULADO = S.CD_SIMULADO ");
        sbSql.append("   AND A.CD_CONCURSO = Q.CD_CONCURSO ");
        sbSql.append("   AND A.CD_MATERIA  = Q.CD_MATERIA  ");
        sbSql.append("   AND A.CD_QUESTAO  = Q.CD_QUESTAO  ");
        sbSql.append("   AND A.CD_USUARIO  = ? ");
        sbSql.append("   AND A.CD_SIMULADO = ? ");

        List<SimuladoUsuarioQuestao> simuladoQuestaosList = new ArrayList<SimuladoUsuarioQuestao>(100);
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, codigoUsuario);
            setInt(ps, pos++, codigoSimulado);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                SimuladoUsuarioQuestao simuladoQuestao = fromResultSet(rs);
                simuladoQuestaosList.add(simuladoQuestao);
            }
            close(rs);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoUsuarioQuestaoDAO.findBySimulado (" + sqle.getMessage() + ")");
        }
        return simuladoQuestaosList;
    }

    public static List<SimuladoUsuarioQuestao> findByQuestao(int codigoConcurso, int codigoMateria, int codigoQuestao,
            Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("SELECT A.CD_USUARIO             CD_USUARIO            ");
        sbSql.append("     , A.CD_SIMULADO            CD_SIMULADO           ");
        sbSql.append("     , S.TX_INDENTIFICACAO      TX_INDENTIFICACAO     ");
        sbSql.append("     , S.TX_DESCRICAO           TX_DESCRICAO          ");
        sbSql.append("     , S.ID_SITUACAO            ID_SITUACAO_SIMULADO  ");
        sbSql.append("     , S.TS_CADASTRO            TS_CADASTRO_SIMULADO  ");
        sbSql.append("     , A.CD_CONCURSO            CD_CONCURSO           ");
        sbSql.append("     , A.CD_MATERIA             CD_MATERIA            ");
        sbSql.append("     , A.CD_QUESTAO             CD_QUESTAO            ");
        sbSql.append("     , Q.ID_SITUACAO            ID_SITUACAO_QUESTAO   ");
        sbSql.append("     , Q.TX_QUESTAO             TX_QUESTAO            ");
        sbSql.append("     , Q.TX_COMENTARIO          TX_COMENTARIO_QUESTAO ");
        sbSql.append("     , A.CD_ITEM_RESPOSTA       CD_ITEM_RESPOSTA      ");
        sbSql.append("     , A.TX_COMENTARIO          TX_COMENTARIO_RESPOSTA");
        sbSql.append("  FROM SIMULADO_USUARIO_QUESTAO A ");
        sbSql.append("     , SIMULADO_USUARIO         S ");
        sbSql.append("     , QUESTAO                  Q ");
        sbSql.append(" WHERE A.CD_USUARIO  = S.CD_USUARIO  ");
        sbSql.append("   AND A.CD_SIMULADO = S.CD_SIMULADO ");
        sbSql.append("   AND A.CD_CONCURSO = Q.CD_CONCURSO ");
        sbSql.append("   AND A.CD_MATERIA  = Q.CD_MATERIA  ");
        sbSql.append("   AND A.CD_QUESTAO  = Q.CD_QUESTAO  ");
        sbSql.append("   AND A.CD_CONCURSO = ? ");
        sbSql.append("   AND A.CD_MATERIA  = ? ");
        sbSql.append("   AND A.CD_QUESTAO  = ? ");

        List<SimuladoUsuarioQuestao> simuladoQuestaosList = new ArrayList<SimuladoUsuarioQuestao>(100);
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, codigoConcurso);
            setInt(ps, pos++, codigoMateria);
            setInt(ps, pos++, codigoQuestao);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                SimuladoUsuarioQuestao simuladoQuestao = fromResultSet(rs);
                simuladoQuestaosList.add(simuladoQuestao);
            }
            close(rs);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoUsuarioQuestaoDAO.findByQuestao (" + sqle.getMessage() + ")");
        }
        return simuladoQuestaosList;
    }

    public static void insert(SimuladoUsuarioQuestao simuladoQuestao, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("INSERT INTO SIMULADO_USUARIO_QUESTAO ");
        sbSql.append("     ( CD_USUARIO       ");
        sbSql.append("     , CD_SIMULADO      ");
        sbSql.append("     , CD_CONCURSO      ");
        sbSql.append("     , CD_MATERIA       ");
        sbSql.append("     , CD_QUESTAO       ");
        sbSql.append("     , CD_ITEM_RESPOSTA ");
        sbSql.append("     , TX_COMENTARIO    ");
        sbSql.append(") VALUES (?,?,?,?,?,?,?)");

        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, simuladoQuestao.getSimuladoUsuario().getUsuario().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getSimuladoUsuario().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getConcurso().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getMateria().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getItemResposta(), true);
            setString(ps, pos++, simuladoQuestao.getComentarioResposta(), true);
            ps.executeUpdate();
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoUsuarioQuestaoDAO.insert (" + sqle.getMessage() + ")");
        }
    }

    public static void update(SimuladoUsuarioQuestao simuladoQuestao, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("UPDATE SIMULADO_USUARIO_QUESTAO ");
        sbSql.append("   SET CD_ITEM_RESPOSTA  = ? ");
        sbSql.append("     , TX_COMENTARIO     = ? ");
        sbSql.append(" WHERE CD_USUARIO        = ? ");
        sbSql.append("   AND CD_SIMULADO       = ? ");
        sbSql.append("   AND CD_CONCURSO       = ? ");
        sbSql.append("   AND CD_MATERIA        = ? ");
        sbSql.append("   AND CD_QUESTAO        = ? ");

        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, simuladoQuestao.getItemResposta(), true);
            setString(ps, pos++, simuladoQuestao.getComentarioResposta(), true);
            setInt(ps, pos++, simuladoQuestao.getSimuladoUsuario().getUsuario().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getSimuladoUsuario().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getConcurso().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getMateria().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getCodigo());
            ps.executeUpdate();
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoUsuarioQuestaoDAO.update (" + sqle.getMessage() + ")");
        }
    }

    public static void delete(SimuladoUsuarioQuestao simuladoQuestao, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("DELETE FROM SIMULADO_USUARIO_QUESTAO  ");
        sbSql.append(" WHERE CD_USUARIO  = ? ");
        sbSql.append("   AND CD_SIMULADO = ? ");
        sbSql.append("   AND CD_CONCURSO = ? ");
        sbSql.append("   AND CD_MATERIA  = ? ");
        sbSql.append("   AND CD_QUESTAO  = ? ");

        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, simuladoQuestao.getSimuladoUsuario().getUsuario().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getSimuladoUsuario().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getConcurso().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getMateria().getCodigo());
            setInt(ps, pos++, simuladoQuestao.getQuestao().getCodigo());
            ps.executeUpdate();
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoUsuarioQuestaoDAO.delete (" + sqle.getMessage() + ")");
        }
    }

    public static void deleteBySimulado(SimuladoUsuario simulado, Connection conn) throws TransactionException {

        StringBuffer sbSql = new StringBuffer();
        sbSql.append("DELETE FROM SIMULADO_USUARIO_QUESTAO  ");
        sbSql.append(" WHERE CD_USUARIO  = ? ");
        sbSql.append("   AND CD_SIMULADO = ? ");
        try {
            PreparedStatement ps = conn.prepareStatement(sbSql.toString());
            int pos = 1;
            setInt(ps, pos++, simulado.getUsuario().getCodigo());
            setInt(ps, pos++, simulado.getCodigo());
            ps.executeUpdate();
            close(ps);
        } catch (SQLException sqle) {
            throw new TransactionException("SimuladoUsuarioQuestaoDAO.deleteBySimulado (" + sqle.getMessage() + ")");
        }
    }

    private static SimuladoUsuarioQuestao fromResultSet(ResultSet rs) throws SQLException {

        // SIMULADO QUESTAO
        SimuladoUsuarioQuestao simuladoQuestao = new SimuladoUsuarioQuestao();
        // SIMULADO
        SimuladoUsuario simulado = new SimuladoUsuario();
        simulado.getUsuario().setCodigo(getInt(rs, "CD_USUARIO"));
        simulado.setCodigo(getInt(rs, "CD_SIMULADO"));
        simulado.setIdentificacao(getString(rs, "TX_INDENTIFICACAO"));
        simulado.setDescricao(getString(rs, "TX_DESCRICAO"));
        simulado.setSituacao(SimuladoUsuarioSituacao.getSituacaoById(getByte(rs, "ID_SITUACAO_SIMULADO")));
        simulado.setDataCadastro(getDateFromTimestamp(rs, "TS_CADASTRO_SIMULADO"));
        simuladoQuestao.setSimuladoUsuario(simulado);
        // QUESTAO
        Questao questao = new Questao();
        questao.getConcurso().setCodigo(getInt(rs, "CD_CONCURSO"));
        questao.getMateria().setCodigo(getInt(rs, "CD_MATERIA"));
        questao.setCodigo(getInt(rs, "CD_QUESTAO"));
        questao.setSituacao(Situacao.getSituacaoById(getByte(rs, "ID_SITUACAO_QUESTAO")));
        questao.setTexto(getString(rs, "TX_TEXTO_QUESTAO"));
        questao.setComentario(getString(rs, "TX_COMENTARIO_QUESTAO"));
        simuladoQuestao.setQuestao(questao);
        //
        simuladoQuestao.setItemResposta(getByte(rs, "CD_ITEM_RESPOSTA"));
        simuladoQuestao.setComentarioResposta(getString(rs, "TX_COMENTARIO_RESPOSTA"));
        //
        return simuladoQuestao;
    }

}
